{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "f1aab367-75f3-4080-976d-8aef06f4d1f5",
   "metadata": {},
   "source": [
    "FastAPI 支持同时使用 File 和 Form 定义文件和表单字段。\n",
    "\n",
    "声明文件可以使用UploadFile \n",
    "\n",
    "可在一个路径操作中声明多个 File 与 Form 参数，但不能同时声明要接收 JSON 的 Body 字段。\n",
    "\n",
    "因为此时请求体的编码为 multipart/form-data，不是 application/json。\r\n",
    "\r\n",
    "这不是 FastAPI 的问题，而是 HTTP 协议的规定。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5649fe59-3e0e-42e6-b060-4b7db5406d2f",
   "metadata": {},
   "source": [
    "创建文件和表单参数的方式与 Body 和 Query 一样："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "f24d725d-7ad5-4eae-b018-caf0e38c2a4b",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:     Started server process [22476]\n",
      "INFO:     Waiting for application startup.\n",
      "INFO:     Application startup complete.\n",
      "INFO:     Uvicorn running on http://0.0.0.0:8009 (Press CTRL+C to quit)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:     127.0.0.1:53126 - \"POST /files/ HTTP/1.1\" 200 OK\n",
      "INFO:     127.0.0.1:53141 - \"POST /files/ HTTP/1.1\" 422 Unprocessable Entity\n",
      "INFO:     127.0.0.1:53146 - \"POST /files/ HTTP/1.1\" 400 Bad Request\n",
      "INFO:     127.0.0.1:53149 - \"POST /files/ HTTP/1.1\" 200 OK\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:     Shutting down\n",
      "INFO:     Waiting for application shutdown.\n",
      "INFO:     Application shutdown complete.\n",
      "INFO:     Finished server process [22476]\n"
     ]
    }
   ],
   "source": [
    "import uvicorn\n",
    "from fastapi import FastAPI, File, Form, UploadFile\n",
    "app = FastAPI()\n",
    "\n",
    "@app.post(\"/files/\")\n",
    "async def create_file(\n",
    "    file: UploadFile = File(), token: str = Form()\n",
    "):\n",
    "    return {\n",
    "        \"token\": token,\n",
    "        \"file_name\": file.filename,\n",
    "    }\n",
    "if __name__ == '__main__':\n",
    "    config = uvicorn.Config(app, host='0.0.0.0', port=8009)\n",
    "    server = uvicorn.Server(config)\n",
    "    await server.serve()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3546ca0f-d6d3-4892-aa25-fe488ab69c52",
   "metadata": {},
   "outputs": [],
   "source": [
    "url = \"http://127.0.0.1:8009/files/\"\n",
    "data = {\"token\": \"bb745154\"}\n",
    "files = {\"file\": open('19.JPG', \"rb\")}\n",
    "res = requests.post(url, data=data, files=files)\n",
    "res.text\n",
    "\n",
    "\n",
    "# 先把一张图片放在和ipynb文件路径相同的地方，命名为 19.JPG\n",
    "# 在另一个ipynb文件中运行代码，会得到 '{\"token\":\"bb745154\",\"file_name\":\"19.JPG\"}'"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
